﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Payroll.Biz.Legacy.Models
{
    public class Employee
    {
        public Guid Id { get; private set; }

        public string Name { get; set; }

        public string Address { get; private set; }

        public IPaymentSchedule Schedule { get; set; }

        public IPaymentMethod Method { get; set; }

        public IAffiliation Affiliation { get; set; }

        public IPaymentClassification Classification { get; set; }

        public Employee(Guid id, string address, IPaymentClassification classification)
        {
            this.Id = id;
            this.Address = address;
            this.Classification = classification;
            this.Affiliation = new NoAffiliation();
        }

        public bool IsPayDate(DateTime date) { return Schedule.IsPayDate(date); }

        public DateTime GetPayPeriodStartDate(DateTime date) { return Schedule.GetPayPeriodStartDate(date); }

        public void Payday(Paycheck paycheck)
        {
            if (Classification == null)
            {
                return;
            }

            decimal grossPay = Classification.CalculatePay(paycheck);
            decimal deductions = Affiliation.CalculateDeductions(paycheck);

            paycheck.GrossPay = grossPay;
            paycheck.Deductions = deductions;

            Method.Pay(paycheck);
        }

        public override string ToString()
        {
            return $"{{{nameof(Id)}={Id.ToString()}, {nameof(Name)}={Name}, {nameof(Address)}={Address}, {nameof(Schedule)}={Schedule}, {nameof(Method)}={Method}, {nameof(Affiliation)}={Affiliation}}}";
        }

        public override bool Equals(object obj)
        {
            if (!(obj is Employee))
            {
                return false;
            }

            Employee employee = (Employee)obj;

            return Id.Equals(employee.Id) &&
                (Name == employee.Name) &&
                (Address == employee.Address) &&
                (Schedule.GetType() == employee.Schedule.GetType()) &&
                EqualityComparer<IPaymentMethod>.Default.Equals(Method, employee.Method) &&
                EqualityComparer<IAffiliation>.Default.Equals(Affiliation, employee.Affiliation) &&
                EqualityComparer<IPaymentClassification>.Default.Equals(Classification, employee.Classification);
        }

        public override int GetHashCode()
        {
            int hashCode = -2073009881;
            hashCode = (hashCode * (-1521134295)) + Id.GetHashCode();
            hashCode = (hashCode * (-1521134295)) + EqualityComparer<string>.Default.GetHashCode(Name);
            hashCode = (hashCode * (-1521134295)) + EqualityComparer<string>.Default.GetHashCode(Address);
            hashCode = (hashCode * (-1521134295)) + EqualityComparer<IPaymentSchedule>.Default.GetHashCode(Schedule);
            hashCode = (hashCode * (-1521134295)) + EqualityComparer<IPaymentMethod>.Default.GetHashCode(Method);
            hashCode = (hashCode * (-1521134295)) + EqualityComparer<IAffiliation>.Default.GetHashCode(Affiliation);
            hashCode = (hashCode * (-1521134295)) +
                EqualityComparer<IPaymentClassification>.Default.GetHashCode(Classification);
            return hashCode;
        }
    }
}
